home *** CD-ROM | disk | FTP | other *** search
/ AOL File Library: 2,801 to 2,900 / aol-file-protocol-4400-2801-to-2900.zip / AOLDLs / C++ Files Library / Graphic Gems I, II & III (C_C++) / Graphics Gems C Code.sea / GemsI / Src / Label.c < prev    next >
C/C++ Source or Header  |  1992-06-16  |  2KB  |  114 lines

  1. /*
  2.  * Nice Numbers for Graph Labels
  3.  * by Paul Heckbert
  4.  * from "Graphics Gems", Academic Press, 1990
  5.  */
  6.  
  7. /*
  8.  * label.c: demonstrate nice graph labeling
  9.  *
  10.  * Paul Heckbert    2 Dec 88
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <math.h>
  15. #include "GraphicsGems.h"
  16.  
  17. double nicenum();
  18.  
  19. /* expt(a,n)=a^n for integer n */
  20.  
  21. #ifdef POW_NOT_TRUSTWORTHY
  22. /* if roundoff errors in pow cause problems, use this: */
  23.  
  24. double expt(a, n)
  25. double a;
  26. register int n;
  27. {
  28.     double x;
  29.  
  30.     x = 1.;
  31.     if (n>0) for (; n>0; n--) x *= a;
  32.     else for (; n<0; n++) x /= a;
  33.     return x;
  34. }
  35.  
  36. #else
  37. #   define expt(a, n) pow(a, (double)(n))
  38. #endif
  39.  
  40. #define NTICK 5            /* desired number of tick marks */
  41.  
  42. main(ac, av)
  43. int ac;
  44. char **av;
  45. {
  46.     double min, max;
  47.  
  48.     if (ac!=3) {
  49.     fprintf(stderr, "Usage: label <min> <max>\n");
  50.     exit(1);
  51.     }
  52.     min = atof(av[1]);
  53.     max = atof(av[2]);
  54.  
  55.     loose_label(min, max);
  56. }
  57.  
  58. /*
  59.  * loose_label: demonstrate loose labeling of data range from min to max.
  60.  * (tight method is similar)
  61.  */
  62.  
  63. loose_label(min, max)
  64. double min, max;
  65. {
  66.     char str[6], temp[20];
  67.     int nfrac;
  68.     double d;                /* tick mark spacing */
  69.     double graphmin, graphmax;        /* graph range min and max */
  70.     double range, x;
  71.  
  72.     /* we expect min!=max */
  73.     range = nicenum(max-min, 0);
  74.     d = nicenum(range/(NTICK-1), 1);
  75.     graphmin = floor(min/d)*d;
  76.     graphmax = ceil(max/d)*d;
  77.     nfrac = MAX(-floor(log10(d)), 0);    /* # of fractional digits to show */
  78.     sprintf(str, "%%.%df", nfrac);    /* simplest axis labels */
  79.  
  80.     printf("graphmin=%g graphmax=%g increment=%g\n", graphmin, graphmax, d);
  81.     for (x=graphmin; x<graphmax+.5*d; x+=d) {
  82.     sprintf(temp, str, x);
  83.     printf("(%s)\n", temp);
  84.     }
  85. }
  86.  
  87. /*
  88.  * nicenum: find a "nice" number approximately equal to x.
  89.  * Round the number if round=1, take ceiling if round=0
  90.  */
  91.  
  92. static double nicenum(x, round)
  93. double x;
  94. int round;
  95. {
  96.     int exp;                /* exponent of x */
  97.     double f;                /* fractional part of x */
  98.     double nf;                /* nice, rounded fraction */
  99.  
  100.     exp = floor(log10(x));
  101.     f = x/expt(10., exp);        /* between 1 and 10 */
  102.     if (round)
  103.     if (f<1.5) nf = 1.;
  104.     else if (f<3.) nf = 2.;
  105.     else if (f<7.) nf = 5.;
  106.     else nf = 10.;
  107.     else
  108.     if (f<=1.) nf = 1.;
  109.     else if (f<=2.) nf = 2.;
  110.     else if (f<=5.) nf = 5.;
  111.     else nf = 10.;
  112.     return nf*expt(10., exp);
  113. }
  114.